#include <read_text/text_detect.h>

#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <string>
#include "std_msgs/String.h"
#include <boost/thread/condition.hpp>

using namespace std;

namespace enc = sensor_msgs::image_encodings;

class TextReader
{
	public:
	ros::NodeHandle nh_;
	image_transport::ImageTransport it_;
	image_transport::Subscriber image_sub_;
	DetectText detector;
	ros::Publisher word_pub;
	ros::Time last_detection;
	
	cv_bridge::CvImagePtr cv_ptr;
	cv::Mat matimg;
	
	
	TextReader(const char* correlation, 
			const char* dictionary)
		: it_(nh_)
	{
		image_sub_ = it_.subscribe("camera/rgb/image_rect_color",
				1, &TextReader::imageCb, this);
		word_pub = nh_.advertise<std_msgs::String>("readWords", 1000);
		detector = DetectText();
		detector.readLetterCorrelation(correlation);
		detector.readWordList(dictionary);
		last_detection = ros::Time::now();
		
	}

	~TextReader()
	{}

	// call back function 
	void imageCb(const sensor_msgs::ImageConstPtr& msg)
	{
		ros::Time now = ros::Time::now();
		if (now - last_detection >= ros::Duration(5)) {
			try
			{
				cv_ptr = cv_bridge::toCvCopy(msg, enc::BGR8);
				matimg = cv::Mat(cv_ptr->image.rows, cv_ptr->image.cols, CV_8UC3);
				cv::Mat img = matimg.clone();
				detector.detect(img);
				vector<string> detectedWords = detector.getWords();
				for(size_t i = 0; i < detectedWords.size(); i++) {
					std_msgs::String str;
					str.data = detectedWords[i];
					//ROS_INFO("%s", str.data.c_str());
					word_pub.publish(str);
				}
				detectedWords.clear();
				
				last_detection = ros::Time::now();
			}
			catch (cv_bridge::Exception& e)
			{
				ROS_ERROR("cv_bridge exception: %s", e.what());
				return;
			}
		}
		
	}
};

int main(int argc, char** argv)
{
	if (argc < 3)
	{
		ROS_ERROR( "not enought input: read_text <correlation> <dictionary>");
		return 1;
	}
	ros::init(argc, argv, "readText");
	TextReader reader(argv[1], argv[2]);
	
	ros::Rate r(5);
	while (ros::ok()) {
		ros::spinOnce();
		r.sleep();
	}
	return 0;
}
